/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package SynchronizationLayer.Registration;

import DataModel.EntryStatus;
import DataModel.NotaryCertificate;
import DataModel.NotaryEntry;
import Repository.IRepositoryProxy;
import SynchronizationLayer.ExpectedPacket;
import SynchronizationLayer.IPacketHandler;
import SynchronizationLayer.ISynchronizationServer;
import SynchronizationLayer.NotarySynchronizationMessage;
import SynchronizationLayer.NotarySynchronizationMessageType;
import SynchronizationLayer.NotarySynchronizationPacket;
import SynchronizationLayer.PacketHandlerResult;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.joda.time.DateTime;

public class RegistrationPacketHandler implements IPacketHandler
{
	@Override
	public PacketHandlerResult handle( NotarySynchronizationPacket notarySynchronizationPacket, IRepositoryProxy repositoryProxy, ISynchronizationServer synchronizationServer )
	{
		switch ( notarySynchronizationPacket.getNotarySynchronizationMessage().getNotarySynchronizationMessageType() )
		{
			case RegistrationSyn:
			{
				handleRegistrationSyn(notarySynchronizationPacket, repositoryProxy, synchronizationServer);
				break;
			}
			case RegistrationSynAck:
			{
				//jak rozwiazac timeout?
				//zanotowac ze odebrano
				//jezeli to jest ostatnia synack, to wyslac ack
				break;
			}
			case RegistrationAck:
			{
				//zapisac ze klucz jest final
				break;
			}
			case ERROR_NameIsBusy:
			{
				//tam gdzie odebranoc synack, odeslac ze klucz sie wycofuje

				break;
			}
			case ERROR_KeyIsBusy:
			{
				//analogicznie jak ERROR_NameIsBusy
			}
			break;
			case RegistrationReject:
			{
				//usunac klucz z bazy
				break;
			}
			default:
				throw new InvalidParameterException("NotarySynchronizationMessageType");
		}

		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
	}

	private void handleRegistrationSyn( NotarySynchronizationPacket notarySynchronizationPacket, IRepositoryProxy repositoryProxy, ISynchronizationServer synchronizationServer )
	{
		try
		{
			RegistrationPayload payload = ( RegistrationPayload ) notarySynchronizationPacket.getNotarySynchronizationMessage().getPayload();
			NotaryCertificate certificate = payload.getCertificate();

			RegistrationPayload responsePayload = new RegistrationPayload();
			switch ( repositoryProxy.checkConflict(certificate) )
			{
				case Name:
				{
					responsePayload.setCertificate(new NotaryCertificate(certificate.getName(), null));
					synchronizationServer.sendResponse(new NotarySynchronizationMessage(
									NotarySynchronizationMessageType.ERROR_NameIsBusy, responsePayload),
																						 notarySynchronizationPacket.getSourceAddress(),
																						 notarySynchronizationPacket.getSourcePort());
					break;
				}
				case Key:
				{
					responsePayload.setCertificate(certificate);
					synchronizationServer.sendResponse(new NotarySynchronizationMessage(
									NotarySynchronizationMessageType.ERROR_KeyIsBusy, responsePayload),
																						 notarySynchronizationPacket.getSourceAddress(),
																						 notarySynchronizationPacket.getSourcePort());
					break;

				}
				case None:
				{
					responsePayload.setCertificate(certificate);
					repositoryProxy.saveEntry(new NotaryEntry(certificate.getName(), certificate.getPublicKey(),
																										EntryStatus.New, DateTime.now()));
					synchronizationServer.sendResponse(new NotarySynchronizationMessage(
									NotarySynchronizationMessageType.RegistrationSynAck, responsePayload),
																						 notarySynchronizationPacket.getSourceAddress(),
																						 notarySynchronizationPacket.getSourcePort());
					break;
				}
				default:
					throw new InvalidParameterException("CertificateConflict");
			}
		}
		catch ( IOException ex )
		{
			Logger.getLogger(RegistrationPacketHandler.class.getName()).log(Level.SEVERE, null, ex);
		}
		catch ( ClassNotFoundException ex )
		{
			Logger.getLogger(RegistrationPacketHandler.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	private void handleRegistrationSynAck( NotarySynchronizationPacket notarySynchronizationPacket, IRepositoryProxy repositoryProxy, ISynchronizationServer synchronizationServer )
	{

	}

	@Override
	public void handleTimeout( IRepositoryProxy repositoryProxy, ISynchronizationServer synchronizationServer )
	{
		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.	}
	}

	@Override
	public void setExpectedPackets( PacketHandlerResult handlerResult, ArrayList<ExpectedPacket> expectedPackets )
	{
		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
	}
}
